package engine.audio;

import java.util.ArrayList;

import engine.Constants;


/**
 * AudioManager
 * The AudioManager is responsible for taking channel outputs and mixing them
 * down into a single audio buffer before sending the audio data off to the
 * Platform for playing.
 **/
public final class AudioManager {
	/**
	 * CtoR
	 * @param outBuffer - the platform's audiobuffer.
	 **/
	public AudioManager(AudioBuffer_I outBuffer) {
		_OutBuffer = outBuffer;
		_Mixer = new Mixer(Constants.AUDIO_LATENCY);
		_Channels = new ArrayList<Channel>();
	}
	/**
	 * Removes a channel from the audio manager. 
	 * @param channel - the Channel instance to remove.
	 * @return true if the channel was renived, otherwise false.
	 **/
	public boolean removeChannel(Channel channel) {
		if(channel == null) {
			return false;
		}
		return _Channels.remove(channel);
	}
	/**
	 * Adds a channel to the existing channel list.
	 * @param channel - the Channel instance to add.
	 * @return true if the channel was added, otherwise false.
	 **/
	public boolean addChannel(Channel channel) {
		if(channel == null) {
			return false;
		}
		return _Channels.add(channel);
	}
	/**
	 * @param index - the index of the channel to return.
	 * @return the channel at a given index, otherwise null
	 **/
	public Channel getChannel(int index) {
		if(index < 0 || index > _Channels.size()) {
			return null;
		}
		return _Channels.get(index);
	}
	/**
	 * @param name - the name to lookup.
	 * @return the channel with the given name, otherwise null
	 **/
	public Channel getChannel(String name) {
		if(name == null) {
			return null;
		}
		for(Channel c : _Channels) {
			if(c.getName() == name) {
				return c;
			}
		}
		return null;
	}
	/**
	 * Fills the ourput buffer and plays any pending audio data with regards
	 * to time.
	 * @return the number of samples generated to fill the output buffefr.
	 **/
	public int play() {
		if(_OutBuffer == null) {
			return 0;
		}
		int sampleCount = _OutBuffer.getFree();
		Channel[] channels = _Channels.toArray(new Channel[_Channels.size()]);
		if(channels.length == 0) {
			return 0;
		}
			
		for(Channel c : channels) {
			c.generate(sampleCount);
		}
		_Mixer.mix(channels, sampleCount);
		_OutBuffer.fill(_Mixer._Buffer, sampleCount);
		return sampleCount;
	}
	
	private Mixer _Mixer;
	private AudioBuffer_I _OutBuffer;
	private ArrayList<Channel> _Channels;
}